package tcln.gxtx.client.utils.lang;

import java.util.Comparator;

/**
 * Helper for objects in client-side. Mainly this class contains utility methods from
 * <code>org.apache.commons.lang.ObjectUtils</code>.
 * 
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public final class GwtObjectUtils {

    /**
     * Compares two objects for equality, where either one or both objects may be <code>null</code>.
     * 
     * @param object1
     *            the first object, may be <code>null</code>
     * @param object2
     *            the second object, may be <code>null</code>
     * @return <code>true</code> if the values of both objects are the same.
     * @see org.apache.commons.lang.ObjectUtils
     */
    public static boolean equals(Object object1, Object object2) {
        if (object1 == object2) {
            return true;
        }
        if ((object1 == null) || (object2 == null)) {
            return false;
        }
        return object1.equals(object2);
    }

    /**
     * Compares two objects for equality, where either one or both objects may be <code>null</code>, via a optional
     * custom comparator. If this comparator is <code>null</code>, this method behaves like
     * {@link #equals(Object, Object)} .
     * 
     * @param <T> Actual object type.
     * @param object1
     *            the first object, may be <code>null</code>
     * @param object2
     *            the second object, may be <code>null</code>
     * @param comparator
     *            A custom comparator for equal comparison.
     * @return <code>true</code> if the values of both objects are the same.
     * @see org.apache.commons.lang.ObjectUtils
     */
    public static <T> boolean equals(T object1, T object2, Comparator<T> comparator) {
        if (object1 == object2) {
            return true;
        }
        if ((object1 == null) || (object2 == null)) {
            return false;
        }

        if (comparator != null) {
            return comparator.compare(object1, object2) == 0;
        }
        return object1.equals(object2);
    }

    /**
     * Compares two objects for non-equality, where either one or both objects may be <code>null</code>.
     * 
     * @param object1
     *            the first object, may be <code>null</code>
     * @param object2
     *            the second object, may be <code>null</code>
     * @return !{@link #equals(Object, Object)}.
     */
    public static boolean notEquals(Object object1, Object object2) {
        return !equals(object1, object2);
    }

    /**
     * Gets the toString that would be produced by <code>Object</code> if a class did not override toString itself.
     * <code>null</code> will return empty string.
     * <p>
     * <b>Remark</b>: class package is NOT included in the generated identity.
     * 
     * @param object
     *            Objecc to generate identity.
     * @return
     */
    public static String identityToString(Object object) {
        return identityToString(object, true);
    }

    /**
     * Gets the toString that would be produced by <code>Object</code> if a class did not override toString itself.
     * <code>null</code> will return empty string.
     * 
     * @param object
     *            Objecc to generate identity.
     * @param packageExcluded
     *            <code>true</code> if package name should be excluded from the generated identity.
     * @return
     * @see org.apache.commons.lang.ObjectUtils#identityToString(Object)
     */
    public static String identityToString(Object object, boolean packageExcluded) {
        if (object == null) {
            return "";
        }

        StringBuilder builder = new StringBuilder();
        if (packageExcluded) {
            builder.append(GwtStringUtils.getClassSimpleName(object.getClass()));
        } else {
            builder.append(object.getClass().getName());
        }
        builder.append('@');
        builder.append(Integer.toHexString(System.identityHashCode(object)));
        return builder.toString();
    }
}
